package simulaco.business;

import gminet.infra.business.BusinessException;
import gminet.infra.business.BusinessObject;
import gminet.infra.db.Transaction;
import gminet.infra.db.TransactionException;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

import simulaco.dao.SimuladoModeloMateriaDAO;
import simulaco.dto.Concurso;
import simulaco.dto.Materia;
import simulaco.dto.Questao;
import simulaco.dto.SimuladoModelo;
import simulaco.dto.SimuladoModeloMateria;

public class SimuladoModeloMateriaBusiness extends BusinessObject {

    public static List<SimuladoModeloMateria> findBySimuladoModelo(int codigoSimulado) throws TransactionException {

        List<SimuladoModeloMateria> listaSimuladoMateria = null;
        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            // QUESTAO
            listaSimuladoMateria = findBySimuladoModelo(codigoSimulado, conn);
            // COMMIT
            transaction.commit();
            //
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
        return listaSimuladoMateria;
    }

    public static List<SimuladoModeloMateria> findBySimuladoModelo(int codigoSimulado, Connection conn)
            throws TransactionException {

        return SimuladoModeloMateriaDAO.findBySimulado(codigoSimulado, conn);
    }

    protected static void insert(SimuladoModeloMateria simuladoMateria) throws BusinessException, TransactionException {

        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            // QUESTAO
            SimuladoModeloMateriaDAO.insert(simuladoMateria, conn);
            // COMMIT
            transaction.commit();
            //
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
    }

    protected static void insertFromSimuladoModelo(SimuladoModelo simulado, Connection conn) throws BusinessException,
            TransactionException {

        List<SimuladoModeloMateria> simuladoMaterias = simulado.getListaSimuladoMaterias();
        if (simuladoMaterias.size() == 0) {
            throw new BusinessException("Nenhuma matéria foi incluida. Pelo menos uma materia deve ser adicionado.");
        }
        for (SimuladoModeloMateria simuladoMateria : simuladoMaterias) {
            simuladoMateria.setSimuladoModelo(simulado);
            if (SimuladoModeloMateriaDAO.findByPK(simuladoMateria, conn) == null) {
                if (simuladoMateria.getQuantidadeQuestoes() == 0) {
                    throw new BusinessException("A quantidade de questões por matéria deve ser maior que zero(0).");
                }
                // VERIFICA SE TEM QUANTIDADE DE QUESTOES DESEJADAS DISPONIVEL
                List<Questao> listaQuestoes = new ArrayList<Questao>();
                int materiaId = simuladoMateria.getMateria().getCodigo();
                int orgaoId = simulado.getOrgao().getCodigo();
                int instituicaoId = simulado.getInstituicao().getCodigo();
                int nivelId = simulado.getNivel().getCodigo();
                List<Concurso> listaConcurso = ConcursoBusiness.findByOrgaoInstituicaoNivel(orgaoId, instituicaoId,
                        nivelId, conn);
                // ADICIONA QUESTOES A LISTA
                for (Concurso concurso : listaConcurso) {
                    int concursoId = concurso.getCodigo();
                    listaQuestoes.addAll(QuestaoBusiness.findByConcursoMateria(concursoId, materiaId, conn));
                }
                if (simuladoMateria.getQuantidadeQuestoes() > listaQuestoes.size()) {
                    Materia materia = MateriaBusiness.findByPK(materiaId, conn);
                    throw new BusinessException("A quantidade de questões é maior que a quantidade disponível para ."
                            + materia.getNome() + " (" + listaQuestoes.size() + ").");
                }
                // INSERE SIMULADO MATERIA
                SimuladoModeloMateriaDAO.insert(simuladoMateria, conn);
            } else {
                throw new BusinessException("Matérias repetidas foram incluidas. Verifique a lista de  materias.");
            }
        }
    }

    protected static void updateFromSimulado(SimuladoModelo simulado, Connection conn) throws BusinessException,
            TransactionException {

        // EXCLUI MATERIAS ANTERIORES DO SIMULADO
        deleteBySimulado(simulado, conn);
        // INCLUI NOVAS MATERIAS DO SIMULADO
        insertFromSimuladoModelo(simulado, conn);
    }

    protected static void update(SimuladoModeloMateria simuladoMateria) throws BusinessException, TransactionException {

        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            // QUESTAO
            SimuladoModeloMateriaDAO.update(simuladoMateria, conn);
            // COMMIT
            transaction.commit();
            //
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
    }

    public static void deleteBySimulado(SimuladoModelo simulado, Connection conn) throws TransactionException {

        SimuladoModeloMateriaDAO.deleteBySimulado(simulado, conn);
    }

}
